home *** CD-ROM | disk | FTP | other *** search
/ CD Actual 1 / PC Actual CD 01.iso / f1 / mdisk25.arj / MDRIVE.PAS < prev    next >
Encoding:
Pascal/Delphi Source File  |  1994-09-29  |  13.3 KB  |  471 lines

  1. {$A+,B-,D-,E-,F-,G+,I+,L-,N-,O-,R-,S-,V+,X-}
  2. Unit Mdrive;
  3. Interface
  4. Uses Dos,Objects;
  5.  
  6. { (c) Emilio David Diaus López 1994                             }
  7. { MicroDrive: subconjunto de útiles para el acceso a disquetes  }
  8. { Es un subconjunto de las funciones existentes en Superdrv.pas }
  9. {
  10. 7. Mdrive: MαDulo De Manejo De Disquetes
  11.  
  12. Este MóDulo Ha Sido DiseñAdo Mediante La ProgramacióN Orientada
  13. A Objetos Y Realiza Las Funciones De AnáLisis De Unidades De
  14. Disquete, Escritura, Lectura Y Formato De Pistas Y Cambio De
  15. ParáMetros.
  16.  
  17. El Objeto Fundamental De Este MóDulo Es Tdrive, Objeto En El
  18. Que EstáN Todos Los MéTodos Y Variables Necesarios Para Operar
  19. Con Disquetes.
  20.  
  21.      
  22. En El Objeto Mencionado Por Una Parte Tenemos Los Datos Del
  23. Disquete Y Por Otra Los MéTodos De Acceso Al Disquete, Dentro De
  24. Estos úLtimos Tenemos :
  25.  
  26.       Constructor Init (Unidad:Byte); 
  27.      Inicializa El Objeto Y Analiza El Disquete
  28.      Identificado Con El NúMero De Unidad LóGica Unidad.
  29.      Function Actualizar :Word; 
  30.      Actualiza Los Datos Del  Disquete Introducido En La
  31.      Unidad LóGica Actual.
  32.      Function Leesector;  
  33.      Lee Un Sector Del Disquete.
  34.      Function Leepista; 
  35.      Lee Una Pista Del Disquete.
  36.  
  37. El Contenido Del Sector Se Almacena En Disco.Sector Y El
  38. Contenido De La Pista En Disco.Pista. 
  39. Las Funciones De Manejo De Sectores Necesitan Tres ParáMetros,
  40. La Cara Del Disquete (0 O 1), El NúMero De Pista Donde Esta El
  41. Sector (40,80) Y El NúMero De Sector Que Queremos Leer o
  42. Escribir.
  43.      Function Grabapista; 
  44.      Graba El Contenido De Disco.Pista En Una Pista FíSica
  45.      Del Disquete Actual.
  46.      Function Verificapista; 
  47.      Verifica Una Pista Determinada.
  48.      Function Format; 
  49.      Da Formato A Una Pista, Antes De Realizar Ningún
  50.      Formato Hay Que Definir El Tipo De Medio Adecuado Para
  51.      El Formato De La Unidad Por Medio Del MéTodo
  52.      Definemedio.
  53. Las Funciones De Pistas Necesitan  Dos ParáMetros: La Cara Del
  54. Disquete (0 O 1) Y El NúMero De Pista (40,80).
  55.  
  56.      Procedure Reinicia_Unidad; 
  57.      Se Encarga De Reiniciar La Unidad Actual En Caso De
  58.      Que Haya Ocurrido Un Error O Al Efectuar El AnáLisis
  59.      De Un Disquete.
  60.  
  61.  
  62.  
  63.  
  64.      Function Buscar_Tipo_Unidad;
  65.      Devuelve El CóDigo De La Unidad Actual, Los CóDigos
  66.      Posibles Son: 
  67.  
  68.      Tipo                CóDigo
  69.      51/4 320/360 Kb     01h
  70.      51/4 1200 Kb        02h
  71.      31/2   720 Kb       03h
  72.      31/2  1440 Kb       04h
  73.      31/2  2880 Kb       05h
  74.  
  75.  
  76.      El úLtimo De Unidades De Extra Densidad ( 31/2 2880 Kb
  77. CóDigo 05H) Hay Que Suponerlo Porque Es Reciente Su
  78. ImplementacióN Y Puede No Estar Estandarizado. Todos Los
  79. NúMeros De La Tabla Que Finalizan Con 'h' Son En
  80. Formato Hexadecimal.
  81.  
  82.     Function Leer_Arranque;
  83.      Lee El Sector De Arranque Del Disquete Y Lo Coloca En
  84.      La Matriz De Bytes Arranque Para Su Posterior
  85.      Procesamiento Por El MéTodo Actualizar.
  86.     Destructor Done;Virtual;
  87.      Reinicializa La Unidad De Disquete Y Finaliza La
  88.      GestióN De Los Disquetes.
  89.  
  90.     Function Calcula_Capacidad:Byte;
  91.      Se Sirve De La FuncióN Del Dos A.P.I 36H Para
  92.      Averiguar Parte De Los ParáMetros LóGicos Del Disquete
  93.      Introducido.
  94.  
  95. AdemáS De Estas Funciones Hay Dos Que Toman Como Base Las
  96. Interrupciones Int 25H E Int 26H Del Dos Para Acceder A Los
  97. Disquetes Mediante Sectores LóGicos En Vez De Acceder Por Medio
  98. De Sectores FíSicos. Su ImplementacióN Requiere Ensamblador
  99. Porque Una Llamada Directa Cuelga El Ordenador, Para Que Esto No
  100. Ocurra Se Introduce DespuéS De La Llamada La InstruccióN 'popf'
  101. Que Coloca Los Flags En El Stack, Esto Es Requerido Para El
  102. Correcto Funcionamiento De Esta FuncióN.
  103.  
  104. El Procedimiento De Funcionamiento Es El Normal En Estos Casos,
  105. Inicializar El Disquete Por Medio De Init, Efectuar Las Acciones
  106. Necesarias Y Finalizar Su Funcionamiento Con Done.
  107. }
  108. Const
  109.       Cread   =2;
  110.       Cwrite  =3;
  111.       Cverify =4;
  112.       Cformat =5;
  113. Const
  114.      Cerrbytessecinc = $81; { Bytes por sector no válido }
  115.      Cerrsecporclinc = $82; { Sectores por cluster no válido }
  116.      Cerrdescrmedinc = $83; { Descriptor de medio no válido }
  117.      Cerrsecporpinc  = $84; { Sectores por pista no válido }
  118.      Cerrnumheadinc  = $85; { Número de cabezas no válido }
  119.      Cerrunidileg    = $86; { Unidad ilegible }
  120.      Cerrunidadvacia = $8002;
  121.  
  122.  
  123. { Tipos necesarios }
  124. Type Tipounidad=(Knone,K360,K1200,K720,K1440,K2880); { Tipos de unidad }
  125.      Tsector=Array [1..512] Of Byte;    { Tipo Sector de 512kb   }
  126.      Tpista=Array[1..512*36] Of Byte;   { Tipo pista }
  127.      Tbuffer  = Array [1..124] Of Byte; { Tipo Buffer para el formato }
  128.      Tstr8    = String [8];             { Tipo de cadena         }
  129.      Ttable   = Array [0..10] Of Byte;  { Tipo de Tabla parametros disco }
  130.      Ptable   =^Ttable;            { Tipo puntero de tabla  }
  131.  
  132. Type
  133.     Tdrive=Object(Tobject)
  134.     { --- Parámetros Físicos --- }
  135.       Numero_Fisico:Byte;
  136.       Cabezas,
  137.       Pistas,Sectores_Por_Pista:Word;
  138.       Adaptador:Byte;
  139.       Tabla                     : Tbuffer;
  140.       Ptabpardis                             : Ptable;
  141.     { --- Parámetros Lógicos --- }
  142.       Unidad_Logica                   : Byte;
  143.       Tipo_Unidad                  : Tipounidad;
  144.       Sectores_Reservados,
  145.       Entradas_Dir_Raiz,
  146.       Sectores_Por_Fat,
  147.       Primer_Sector_Logico                   : Word;
  148.       Numero_De_Fats,
  149.       Descriptor_De_Medio             : Byte;
  150.       Sectores_Totales,Clusters_Totales,
  151.       Clusters_Libres,Bytes_Por_Sector         : Word;
  152.       Espacio_Libre,Capacidad_Total,Dirtabla : Longint;
  153.       Sectores_Por_Cluster,
  154.       Bytes_Por_Cluster                : Word;
  155.       Num_Unidades                 : Byte;
  156.       Es_Hd                                  : Boolean;
  157.       Numero_Error                 : Word;
  158.       Sector,Arranque                 : Tsector;
  159.       Pista                                  : Tpista;
  160.       { ** Inicialización ** }
  161.       Constructor Init(Unidad:Byte);
  162.       Function Actualizar:Word;
  163.       { ** Leer ** }
  164.       Function Leesector(Cara,Pist,Sect:Integer):Byte;
  165.       Function Leepista(Cara,Pist:Integer):Byte;
  166.       { ** Grabar ** }
  167.       Function Grabapista(Cara,Pist:Integer):Byte;
  168.       { ** Verificar ** }
  169.       Function Verificapista(Cara,Pist:Integer):Byte;
  170.       { ** Formato ** }
  171.       Function Format(Cara,Pist:Byte):Byte;
  172.       Function Definemedio(Ps:Word;Sp:Byte):Byte;
  173.       Function Definetipo(Tp:Byte):Byte;
  174.       { ** Hardware ** }
  175.       Procedure Reinicia_Unidad;
  176.       Function Buscar_Tipo_Unidad:Tipounidad;
  177.       { ** Cargar y salvar areas ** }
  178.       Function Leer_Arranque:Word;
  179.       { ** Finalización ** }
  180.       Destructor Done;Virtual;
  181.       { ** int 25h int 26h ** }
  182.       Function Abswritesec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;
  183.       Function Absreadsec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;
  184.       Private
  185.       { ** int 13h sectores y pistas ** }
  186.       Function Usasector(Servicio,Cara,Pist,Sect:Integer):Byte;
  187.       Function Usapista(Servicio,Cara,Pist:Integer):Byte;
  188.       { ** Cálculos ** }
  189.       Function Calcula_Capacidad:Byte;
  190.    End;
  191.    
  192. Implementation
  193.  
  194. Constructor Tdrive.Init;
  195. Begin
  196.      Tobject.Init;
  197.      Unidad_Logica:=Unidad;
  198.      Reinicia_Unidad;
  199.      Numero_Error:=Actualizar;
  200. End;
  201.  
  202. Function Tdrive.Usasector(Servicio,Cara,Pist,Sect:Integer):Byte;
  203. Var R:Registers;
  204. Begin
  205.    R.Ah:=Servicio;
  206.    R.Al:=1;
  207.    R.Ch:=Pist;
  208.    R.Cl:=Sect;
  209.    R.Dh:=Cara;
  210.    R.Dl:=Numero_Fisico;
  211.    R.Es:=Seg(Sector);
  212.    R.Bx:=Ofs(Sector);
  213.    Intr($13,R);
  214.    If R.Flags And Fcarry=Fcarry Then
  215.       Usasector:=R.Ah
  216.    Else
  217.       Usasector:=0;
  218. End;
  219.  
  220. Function Tdrive.Leesector(Cara,Pist,Sect:Integer):Byte;
  221. Begin
  222.      Leesector:=Usasector(Cread,Cara,Pist,Sect);
  223. End;
  224.  
  225. Function Tdrive.Grabapista(Cara,Pist:Integer):Byte;
  226. Begin
  227.     Grabapista:=Usapista(Cwrite,Cara,Pist);
  228. End;
  229.     
  230. Function Tdrive.Leer_Arranque:Word;
  231. Begin
  232.      {Leer_Arranque:=Leesector(0,0,1); <- Es lo mismo }
  233.      Leer_Arranque:=Absreadsec(Unidad_Logica,1,0,Ofs(Sector),Seg(Sector));
  234.     Arranque:=Sector;
  235. End;
  236.  
  237. Function Tdrive.Leepista(Cara,Pist:Integer):Byte;
  238. Begin
  239.     Leepista:=Usapista(Cread,Cara,Pist);
  240. End;
  241.  
  242. Function Tdrive.Verificapista(Cara,Pist:Integer):Byte;
  243. Begin
  244.     Verificapista:=Usapista(Cverify,Cara,Pist);
  245. End;
  246.  
  247. Function Tdrive.Usapista(Servicio,Cara,Pist:Integer):Byte;
  248. Var R:Registers;
  249. Begin
  250.      With R Do Begin
  251.       Ax:=Servicio*256+Sectores_Por_Pista;
  252.       Dx:=Cara*256+Numero_Fisico;
  253.           Cx:=Pist*256+1;
  254.           Es:=Seg(Pista);
  255.           Bx:=Ofs(Pista);
  256.      End;
  257.      Intr($13,R);
  258.      If R.Flags And Fcarry=Fcarry Then
  259.     Usapista:=R.Ah
  260.      Else Usapista:=0;
  261. End;
  262.  
  263. Destructor Tdrive.Done;
  264. Begin
  265.      Reinicia_Unidad;
  266.      Tobject.Done;
  267. End;
  268.  
  269. Function Tdrive.Actualizar:Word;
  270. Var B:Byte;
  271.     C:Word;
  272.  
  273. Begin
  274.      Actualizar:=0;
  275.      Repeat
  276.            Numero_Error:=Leer_Arranque;
  277.      Until Not(Numero_Error In [6,3]);
  278.      If Numero_Error>0 Then Begin
  279.     Actualizar:=Numero_Error;
  280.         Numero_Fisico:=Unidad_Logica;
  281.     Exit;
  282.      End;
  283.      Numero_Fisico:=Unidad_Logica;
  284.      Numero_Error:=Calcula_Capacidad;
  285.      If Numero_Error>0 Then Begin
  286.     Actualizar:=Numero_Error;
  287.         Numero_Fisico:=Unidad_Logica;
  288.     Exit;
  289.      End;
  290.      Es_Hd:=Numero_Fisico>=$80;
  291.      Sectores_Por_Pista:=Arranque[25]+Arranque[26]*256;
  292.      If Not(Sectores_Por_Pista In [8,9,15,18,36]) Then Begin
  293.         Actualizar:=Cerrsecporpinc;
  294.         Exit;
  295.      End;
  296.      If Es_Hd Then Numero_Error:=1; { Solo disquetes }
  297.      If Numero_Error>0 Then Begin
  298.         If Numero_Error=1 Then Numero_Error:=Cerrunidileg;
  299.         Actualizar:=Numero_Error;
  300.     Exit;
  301.      End;
  302.      Bytes_Por_Sector:=Arranque[12]+Arranque[13]*256;
  303.      If Bytes_Por_Sector<>512 Then Begin
  304.         Actualizar:=Cerrbytessecinc;
  305.         Exit;
  306.      End;
  307.      Sectores_Por_Cluster:=Arranque[14];
  308.      If Not(Sectores_Por_Cluster In [1,2]) Then Begin
  309.         Actualizar:=Cerrsecporclinc;
  310.         Exit;
  311.      End;
  312.      Sectores_Totales:=Arranque[20]+Arranque[21]*256;
  313.      Descriptor_De_Medio:=Arranque[22];
  314.      If Not(Descriptor_De_Medio In [$F0,$Fc..$Ff,$F9]) Then Begin
  315.         Actualizar:=Cerrdescrmedinc;
  316.         Exit;
  317.      End;
  318.      Cabezas:=Arranque[27]+Arranque[28]*256;
  319.      If Sectores_Totales*Sectores_Por_Pista*Cabezas=0 Then Begin
  320.     Actualizar:=$86;
  321.     Exit;
  322.      End;
  323.      Pistas:=Word(Sectores_Totales Div (Sectores_Por_Pista*Cabezas));
  324.      Entradas_Dir_Raiz:=Arranque[$12];
  325.      Sectores_Reservados:=Arranque[$0F]+Arranque[$10]*256;
  326.      Numero_De_Fats:=Arranque[$11];
  327.      Sectores_Por_Fat:=Arranque[$17];
  328.      Primer_Sector_Logico:=Sectores_Reservados+
  329.      (Numero_De_Fats*Sectores_Por_Fat)+
  330.      (Entradas_Dir_Raiz*32) Div 512;
  331.      Tipo_Unidad:=Buscar_Tipo_Unidad;
  332. End;
  333.  
  334. Function Tdrive.Absreadsec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;Assembler;
  335. Asm
  336.    Push Ds
  337.    Mov Al,u
  338.    Mov Cx,Nsec
  339.    Mov Dx,Psec
  340.    Mov Ds,Segmento
  341.    Mov Bx,Desplazamiento
  342.    Int 25h
  343.    Pushf
  344.    Pop Bx
  345.    Mov Cx,Fcarry
  346.    And Bx,Cx
  347.    Cmp Bx,Fcarry
  348.    Jz  @@1
  349.    Xor Ax,Ax
  350. @@1:
  351.    Popf
  352.    Pop Ds
  353. End;
  354.  
  355. Function Tdrive.Abswritesec(U:Byte;Nsec,Psec,Desplazamiento,Segmento:Word):Word;Assembler;
  356. Asm
  357.    Push Ds
  358.    Mov Al,u
  359.    Mov Cx,Nsec
  360.    Mov Dx,Psec
  361.    Mov Ds,Segmento
  362.    Mov Bx,Desplazamiento
  363.    Int 26h
  364.    Pushf
  365.    Pop Bx
  366.    Mov Cx,Fcarry
  367.    And Bx,Cx
  368.    Cmp Bx,Fcarry
  369.    Jz  @@1
  370.    Xor Ax,Ax
  371. @@1:
  372.    Popf
  373.    Pop Ds
  374. End;
  375.  
  376. Function Tdrive.Calcula_Capacidad:Byte;
  377. Var R:Registers;
  378. Begin
  379.  R.Ax:=$3600;
  380.  R.Dl:=$00+Unidad_Logica+1;
  381.  Msdos(R);
  382.  Sectores_Por_Cluster:=R.Ax;
  383.  Clusters_Libres:=R.Bx;
  384.  Bytes_Por_Sector:=R.Cx;
  385.  Clusters_Totales:=R.Dx;
  386.  Espacio_Libre:=Sectores_Por_Cluster*Clusters_Libres;
  387.  Espacio_Libre:=Espacio_Libre*Bytes_Por_Sector;
  388.  Capacidad_Total:=Sectores_Por_Cluster*Clusters_Totales;
  389.  Capacidad_Total:=Capacidad_Total*Bytes_Por_Sector;
  390.  If R.Ax=$Ffff Then
  391.     Calcula_Capacidad:=$86
  392.  Else
  393.     Calcula_Capacidad:=0;       
  394. End;
  395.  
  396. Function Tdrive.Format(Cara,Pist:Byte):Byte;
  397. Var Sec:Byte;
  398.     R:Registers;
  399. Begin
  400.      With R Do Begin
  401.       Ah:=Cformat;
  402.       Al:=Sectores_Por_Pista;
  403.       Dx:=Cara*256+Numero_Fisico;
  404.       Cx:=Pist*256;
  405.       Es:=Seg(Tabla);
  406.       Bx:=Ofs(Tabla);
  407.      End;
  408.      For Sec:=1 To Sectores_Por_Pista Do Begin
  409.      Tabla[Sec*4-3]:=Pist;
  410.      Tabla[Sec*4-2]:=Cara;
  411.      Tabla[Sec*4-1]:=Sec;
  412.      Tabla[Sec*4]:=2; (* 512 Bytes/Sector *)
  413.      End;
  414.      Intr($13,R);
  415.      If R.Flags And Fcarry=Fcarry Then
  416.     Format:=R.Ah
  417.      Else Format:=0;
  418. End;
  419.  
  420. Procedure Tdrive.Reinicia_Unidad;
  421. Var R:Registers;
  422. Begin
  423.      R.Ah:=0;
  424.      R.Dl:=Numero_Fisico;
  425.      Intr($13,R);
  426. End;
  427.  
  428. Function Tdrive.Definemedio(Ps:Word;Sp:Byte):Byte;
  429. Var R:Registers;
  430. Begin
  431.      R.Ah:=$18;
  432.      R.Ch:=Ps;
  433.      R.Cl:=Sp;
  434.      R.Dl:=Numero_Fisico;
  435.      Intr($13,R);
  436.      If R.Flags And Fcarry=Fcarry Then
  437.     Definemedio:=R.Ah
  438.      Else Begin
  439.      Definemedio:=0;
  440.      Ptabpardis:=Ptr(R.Es,R.Di);
  441.      Dirtabla:=Longint(Ptabpardis);
  442.      Setintvec($1E,Ptabpardis);
  443.      End;
  444.  
  445. End;
  446. (* FuncióN Obsoleta *)
  447. Function Tdrive.Definetipo(Tp:Byte):Byte;
  448. Var R:Registers;
  449. Begin
  450.      R.Ah:=$17;
  451.      R.Al:=Tp;
  452.      R.Dl:=Numero_Fisico;
  453.      Intr($13,R);
  454.      If (R.Flags And 1)=1 Then
  455.     Definetipo:=R.Ah
  456.      Else
  457.      Definetipo:=0;
  458. End;
  459.  
  460. Function Tdrive.Buscar_Tipo_Unidad:Tipounidad;
  461. Var R:Registers;
  462. Begin
  463.      R.Ah:=$08;
  464.      R.Dl:=Numero_Fisico;
  465.      Intr($13,R);
  466.      Buscar_Tipo_Unidad:=Tipounidad(R.Bl);
  467. End;
  468.  
  469.  
  470. End.
  471.